package com.bianguo.android.bprinter.view.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

public class ZoomLayout extends RelativeLayout {

    public static final float MAX_SCALE_SIZE = 6.0f;
    public static final float MIN_SCALE_SIZE = 0.3f;

    private boolean canTranslate, canScale, canRotate, singleScale;
    private float translateX, translateY;
    private float mLastX, mLastY;
    private float mScale, spacing;
    private float rotation, degree;
    private float mCenterX, mCenterY;
    private long clickTime;
    private OnDoubleClickListener onDoubleClickListener;

    public ZoomLayout(Context context) {
        this(context, null);
    }

    public ZoomLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ZoomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        mScale = 1;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mLastX = event.getRawX();
                mLastY = event.getRawY();
                if (event.getX() >= getRight() - 40 && event.getX() <= getRight() &&
                        event.getY() >= getBottom() - 40 && event.getY() <= getBottom()) {
                    singleScale = true;
                    canTranslate = false;
                    canScale = false;
                    canRotate = false;

                    mCenterX = (getRight() - getLeft()) / 2;
                    mCenterY = (getBottom() - getTop()) / 2;
                    float x = event.getX() - mCenterX;
                    float y = event.getY() - mCenterY;
                    spacing = (float) Math.sqrt(x * x + y * y);

                    double radians = Math.atan2(y, x);
                    degree = (float) Math.toDegrees(radians);
                } else {
                    singleScale = false;
                    canTranslate = true;
                    canScale = false;
                    canRotate = false;
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                canTranslate = false;
                singleScale = false;
                if (event.getPointerCount() == 2) {
                    canScale = true;
                    canRotate = true;
                    spacing = getSpacing(event);
                    degree = getDegree(event);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (canTranslate) {
                    //单指平移操作
                    translateX = translateX + event.getRawX() - mLastX;
                    translateY = translateY + event.getRawY() - mLastY;
                    setTranslationX(translateX);
                    setTranslationY(translateY);
                    mLastX = event.getRawX();
                    mLastY = event.getRawY();
                }
                if (canScale) {
                    //双指缩放操作
                    mScale = mScale * getSpacing(event) / spacing;
                    if (mScale > MAX_SCALE_SIZE) {
                        mScale = MAX_SCALE_SIZE;
                    } else if (mScale < MIN_SCALE_SIZE) {
                        mScale = MIN_SCALE_SIZE;
                    }
                    setScaleX(mScale);
                    setScaleY(mScale);
                }
                if (canRotate) {
                    //双指旋转操作
                    rotation = rotation + getDegree(event) - degree;
                    if (rotation > 360) {
                        rotation = rotation - 360;
                    }
                    if (rotation < -360) {
                        rotation = rotation + 360;
                    }
                    setRotation(rotation);
                }
                if (singleScale) {
                    //单指缩放、旋转操作
                    float x = event.getX() - mCenterX;
                    float y = event.getY() - mCenterY;
                    float distance = (float) Math.sqrt(x * x + y * y);
                    mScale = mScale * distance / spacing;
                    if (mScale > MAX_SCALE_SIZE) {
                        mScale = MAX_SCALE_SIZE;
                    } else if (mScale < MIN_SCALE_SIZE) {
                        mScale = MIN_SCALE_SIZE;
                    }
                    setScaleX(mScale);
                    setScaleY(mScale);

                    double radians = Math.atan2(y, x);
                    float tempRotation = (float) Math.toDegrees(radians);
                    rotation = rotation + tempRotation - degree;
                    if (rotation > 360) {
                        rotation = rotation - 360;
                    }
                    if (rotation < -360) {
                        rotation = rotation + 360;
                    }
                    setRotation(rotation);
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                canTranslate = false;
                canScale = false;
                canRotate = false;
                singleScale = false;
                break;
            case MotionEvent.ACTION_UP:
                canTranslate = false;
                canScale = false;
                canRotate = false;
                singleScale = false;
                //两次点击时间小于500ms，表示连续点击两次
                long currentTimeMillis = System.currentTimeMillis();
                if (currentTimeMillis - clickTime <= 500) {
                    if (onDoubleClickListener != null) {
                        onDoubleClickListener.onDoubleClick(this);
                    }
                } else {
                    clickTime = currentTimeMillis;
                }
                break;
        }
        return true;
    }

    // 触碰两点间距离
    private float getSpacing(MotionEvent event) {
        //通过三角函数得到两点间的距离
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 取旋转角度
    private float getDegree(MotionEvent event) {
        //得到两个手指间的旋转角度
        double delta_x = event.getX(0) - event.getX(1);
        double delta_y = event.getY(0) - event.getY(1);
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    public void setOnDoubleClickListener(OnDoubleClickListener onDoubleClickListener) {
        this.onDoubleClickListener = onDoubleClickListener;
    }

    public interface OnDoubleClickListener {
        void onDoubleClick(View view);
    }
}
